/**
 * HelloWorldService.java
 */
package fss.remote;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;
import java.util.Scanner;
import java.util.Set;
import java.util.logging.Logger;

import fss.common.LookupServiceRegistry;
import fss.common.communication.PingRequest;
import fss.common.communication.Request;
import fss.core.config.FssProperties;
import fss.core.logger.FssLogger;
import fss.util.FssUtils;
import fss.util.rmi.RmiId;
import fss.util.rmi.RmiUtils;

/**
 * This test Remote Service class.
 * 
 * @author thinh
 * @deprecated do not run this.
 *
 */
public class HelloMyselfService extends UnicastRemoteObject implements RemoteService {
    private static final long serialVersionUID = 1L;
    /**
     * The logger for this class.
     */
    private Logger logger = null;
    /**
     * The id.
     */
    private RmiId id = null;
    /**
     * The registry id of this service.
     */
    private RmiId registryId = null;
    /**
     * The thread that pings its registry server.
     */
    private Thread ping = new Thread() {
        @Override
        public void run() {
            logger.info("Service Registry Heartbeater started...");
            Thread thisThread = Thread.currentThread();
            while (ping == thisThread) {
                try {
                    Thread.sleep(5 * 1000);
                    try {
                        RmiId rid = null;
                        ServiceRegistry reg = ((ServiceRegistry)RmiUtils.getRemoteObject(registryId));
                        if(reg == null) throw new RemoteException("Attempt to obtain the Remote Service Registry returned a null stub.");
                        rid = reg.getId();
                        logger.info("Registry is alive " + rid);
                        
                        PingRequest request = new PingRequest(id);
                        request.setDestination(rid);
                        request.setMessage("The time is " + FssUtils.formatDate(new Date()) + " and I'm writing this message to myself.");
                        
                        reg.processRequest(request);
                    } catch (RemoteException e) {
                        System.out.println("********************************************************************");
                        logger.warning("Cannot connect to Service Registry: " + e.toString());
                        logger.info("Service Registry Heartbeater preparing to end due to Service Registry failure at " + registryId);                   
                        
                        System.out.println("Service Registry might be down...");
                        // registryId must be reset back to a valid id
                        e.printStackTrace();
                        System.out.println("Looking up now Service Registry...");
                        
                        RmiId _id = LookupServiceRegistry.lookup();
                        if(_id == null) {
                            logger.warning("No available Service Registry is available.");
                        } else {
                            ServiceRegistry registry = (ServiceRegistry)RmiUtils.getRemoteObject(_id);
                            registry.register(HelloMyselfService.this);
                        }
                        System.out.println("********************************************************************");
                    }
                } catch (Exception e) {
                    logger.warning(e.toString());
                }
            }
            logger.info("Service Registry Heartbeater terminated.");
        };
    };
    /**
     * Constructor.
     * @param id the id.
     */
    public HelloMyselfService(RmiId id) throws RemoteException {
        this.id = id;
        logger = FssLogger.getInstance().getRemoteServiceLogger(id.getName());
        String homedir = FssProperties.getInstance().getRemoteServiceHomeDir(id.getName());
        FssUtils.createDirectory(homedir);
        FssUtils.createDirectory(homedir + "/data");
    }
    @Override
    public RmiId getId() throws RemoteException {
        return id;
    }
    @Override
    public void setRegistryId(RmiId id) throws RemoteException {
        logger.info("Setting registry id to " + id);
        this.registryId = id;
        logger.info("HelloWorldService " + id + " starting ping thread.");
        ping.start();
    }
    @Override
    public RmiId getRegistryId() throws RemoteException {
        return registryId;
    }
    @Override
    public void update(Object observable, Object message) throws RemoteException {
        if(!(message instanceof PingRequest)) {
            logger.info("Received message " + message.toString() + " and will NOT process.");
            return;
        }
        logger.info("Processing message " + message.toString());
        PingRequest request = (PingRequest) message;
        logger.info("Received " + request.getClass().getName() + " from " + request.getSource() + " with message [" + request.getMessage() + "].");
    }
    @Override
    public void stop() throws RemoteException {
        Thread _ping = ping;
        ping = null;
        _ping.interrupt();
    }
    /**
     * Application entry for this service.
     * @param args not used.
     * @throws RemoteException error with remote invocation.
     */
    public static void main(String[] args) throws RemoteException {
        String host, name;
        int port;
        Scanner stdin = new Scanner(System.in);
        RemoteService service = null;
        RmiId registryId = null;
        
        System.out.print("Enter registry host: ");
        host = stdin.nextLine();
        System.out.print("Enter registry port: ");
        port = Integer.parseInt(stdin.nextLine());
        System.out.print("Enter registry name: ");
        name = stdin.nextLine();
        registryId = new RmiId(host, name, port);
        
        ServiceRegistry registry = (ServiceRegistry)RmiUtils.getRemoteObject(registryId);
        if(registry == null) {
            throw new RemoteException("Attempt to obtain a Service Registry failed at id " + registryId);
        }
        
        System.out.print("Enter host: ");
        host = stdin.nextLine();
        System.out.print("Enter port: ");
        port = Integer.parseInt(stdin.nextLine());
        System.out.print("Enter service name: ");
        name = stdin.nextLine();
        
        service = new HelloMyselfService(new RmiId(host, name, port));
        RmiUtils.bindRemoteService(service);
        registry.register(service);        
        
        System.out.println("******************************************************************");      
        System.out.println("Hit enter at any time to remove the Service...");
        System.out.println("******************************************************************");
        stdin.nextLine();
        service.stop();
        System.out.println("Service ended.");
    }
    @Override
    public void start() throws RemoteException {
        // TODO Auto-generated method stub
        
    }
    @Override
    public Set<RmiId> getRegisteredClientList() throws RemoteException {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public void processRequest(Request request) throws RemoteException {
        // TODO Auto-generated method stub
        
    }
}
